//
// Created by Snow on 2023/4/3.
//
#include<cstdio>
#include<cstdlib>
#define MaxSize 50
typedef char ElemType;
typedef struct node
{
    ElemType data;
    int ltag,rtag;//增加的线索标记，值为0表示lchild（rchild）指向左（右）孩子结点，为1表示指向前驱（后继）结点
    struct node *lchild;
    struct node *rchild;
}TBTNode;
void CreateTBTree(TBTNode *&b,const char *str)
{
    TBTNode *St[MaxSize],*p=nullptr;
    int top=-1,k,j=0;
    char ch;
    b=nullptr;				//建立的二叉树初始时为空
    ch=str[j];
    while (ch!='\0')	//str未扫描完时循环
    {
        switch(ch)
        {
            case '(':top++;St[top]=p;k=1;break;		//为左节点
            case ')':top--;break;
            case ',':k=2; break;                      	//为右节点
            default:
                p=(TBTNode *)malloc(sizeof(TBTNode));
                p->data=ch;
                p->lchild=p->rchild=nullptr;
                if (b==nullptr)					//*p为二叉树的根节点
                    b=p;
                else  							//已建立二叉树根节点
                {
                    switch(k)
                    {
                        case 1:St[top]->lchild=p;break;
                        case 2:St[top]->rchild=p;break;
                    }
                }
        }
        j++;
        ch=str[j];
    }
}
void DispTBTree(TBTNode *b)
{
    if (b!=nullptr)
    {
        printf("%c",b->data);
        if (b->lchild!=nullptr || b->rchild!=nullptr)
        {
            printf("(");
            DispTBTree(b->lchild);
            if (b->rchild!=nullptr) printf(",");
            DispTBTree(b->rchild);
            printf(")");
        }
    }
}
//中序线索二叉树
TBTNode *pre;//全局变量
void Thread(TBTNode *&p)//对二叉树p进行中序线索化
{
    if(p!=nullptr)
    {
        Thread(p->lchild);//左子树线索化
        if(p->lchild==nullptr)//左孩子不存在，进行前驱结点线索化
        {
            p->lchild=pre;//建立当前结点的前驱结点线索
            p->ltag=1;
        }
        else//p结点的左子树已线索化
        {
            p->ltag=0;
        }
        if(pre->rchild==nullptr)//对pre的后继结点线索化
        {
            pre->rchild=p;//建立前驱结点的后继结点线索
            pre->rtag=1;
        }
        else
        {
            pre->rtag=0;
        }
        pre=p;
        Thread(p->rchild);//右子树线索化
    }
}
TBTNode *CreateThread(TBTNode *b)//中序线索化二叉树
{
    TBTNode *root;
    root=(TBTNode*)malloc(sizeof(TBTNode));//创建头结点
    root->ltag=0;
    root->rtag=1;
    root->rchild=b;
    if(b==nullptr)//空二叉树
        root->lchild=root;
    else
    {
        root->lchild=b;
        pre=root;//pre是结点p的前驱结点，供加线索用
        Thread(b);//中序遍历线索化二叉树
        pre->rchild=root;//最后处理，加入指向头结点的线索
        pre->rtag=1;
        root->rchild=pre;//头结点右线索化
    }
    return root;
}
void ThInOrder(TBTNode *tb)//tb指向中序线索二叉树的头结点
{
    TBTNode *p=tb->lchild;//p指向根节点
    while(p!=tb)
    {
        while(p->ltag==0)//找开始结点
            p=p->lchild;//访问开始结点
        printf("%c ",p->data);
        while(p->rtag==1&&p->rchild!=tb)
        {
            p=p->rchild;
            printf("%c ",p->data);
        }
        p=p->rchild;
    }
}
//递归遍历中序线索树
void InOrder(TBTNode *b)
{
    if(b==nullptr) //如果当前结点为空，直接返回
        return;
    if(b->ltag==0)//如果当前结点的左标志域为0，表示有左孩子，递归调用函数处理左孩子
        InOrder(b->lchild);
    printf("%c",b->data);//输出当前结点的值
    if(b->rtag==0)//如果当前结点的右标志域为0，表示有右孩子，递归调用函数处理右孩子
        InOrder(b->rchild);
}
void DestroyTBTree1(TBTNode *&b)	//销毁
{	if (b->ltag==0)					//节点b有左孩子,释放左子树
        DestroyTBTree1(b->lchild);
    if (b->rtag==0)					//节点b有右孩子,释放右子树
        DestroyTBTree1(b->rchild);
    free(b);
}
void DestroyTBTree(TBTNode *&tb)	//销毁一棵带头结点的中序线索树tb
{
    DestroyTBTree1(tb->lchild);		//释放以tb->lchild为根节点的树
    free(tb);						//释放头节点
}
int main()
{
    TBTNode *b,*tb;
    CreateTBTree(b,"A(B(D(,G)),C(E,F))");
    DispTBTree(b);printf("\n");
    tb=CreateThread(b);
    ThInOrder(tb);printf("\n");
    DestroyTBTree(tb);
    return 1;
}